<?php

use think\exception\ValidateException;
use think\Validate;
use Yaf\Application;
use Yaf\Dispatcher;
use Yaf\Request_Abstract;

if (!function_exists('env')) {
    /**
     * 读取Env环境变量
     * @param string $key 键名
     * @param mixed|null $default 默认值（支持传入匿名函数）
     * @return mixed|null
     */
    function env(string $key, mixed $default = null): mixed
    {
        $value = getenv($key);
        if (false === $value) {
            return value($default);
        }

        switch (strtolower($value)) {
            case 'true':
            case '(true)':
            case 'on':
            case 'yes':
                return true;
            case 'false':
            case '(false)':
            case 'off':
            case 'no':
                return false;
            case 'empty':
            case '(empty)':
                return '';
            case 'null':
            case '(null)':
                return null;
        }

        if (($valueLength = strlen($value)) > 1 && $value[0] === '"' && $value[$valueLength - 1] === '"') {
            return substr($value, 1, -1);
        }
        return $value;
    }
}

if (!function_exists('value')) {
    /**
     * 获取值
     * - 支持匿名函数
     * @param mixed $value
     * @return mixed
     */
    function value(mixed $value): mixed
    {
        return $value instanceof Closure ? $value() : $value;
    }
}

if (!function_exists('env_boolean')) {
    /**
     * 读取Env环境变量，格式化为布尔值
     * @param string $key
     * @return boolean 格式化后的变量
     */
    function env_boolean(string $key): bool
    {
        $value = getenv($key);
        return match (true) {
            is_bool($value) => $value,
            is_numeric($value) => $value > 0,
            is_string($value) => in_array(strtolower($value), ['ok', 'true', 'success', 'on', 'yes', '(ok)', '(true)', '(success)', '(on)', '(yes)']),
            is_array($value) => !empty($value),
            default => (bool)$value,
        };
    }
}


/**
 * 验证器助手函数
 * @param array $data 数据
 * @param array|string $validate 验证器类名或者验证规则数组
 * @param array $message 错误提示信息
 * @param bool $batch 是否批量验证
 * @param bool $failException 是否抛出异常
 * @return bool
 * @throws ValidateException
 */
function validate(array $data, array|string $validate = '', array $message = [], bool $batch = false, bool $failException = true): bool
{
    if (is_array($validate)) {
        $v = new Validate();
        $v->rule($validate);
    } else {
        if (strpos($validate, '.')) {
            // 支持场景
            [$validate, $scene] = explode('.', $validate);
        }
        if (!class_exists($validate)) {
            throw new ValidateException('验证类不存在:' . $validate);
        }
        /** @var Validate $v */
        $v = new $validate();
        if (!empty($scene)) {
            $v->scene($scene);
        }
    }

    return $v->message($message)->batch($batch)->failException($failException)->check($data);
}

/**
 * 获取当前app应用对象
 * @return Application
 */
function app(): Application
{
    return Application::app();
}

/**
 * 获取全局调度器对象
 * @return Dispatcher
 */
function dispatcher(): Dispatcher
{
    return Dispatcher::getInstance();
}

/**
 * 获取全局请求对象
 * @return Request_Abstract
 */
function request(): Request_Abstract
{
    return Dispatcher::getInstance()->getRequest();
}

/**
 * @param string $front
 * @param string $back
 * @return string
 */
function path_combine(string $front, string $back): string
{
    return $front . ($back ? (DIRECTORY_SEPARATOR . ltrim($back, DIRECTORY_SEPARATOR)) : $back);
}

/**
 * 项目基础路径
 * @param string $path
 * @return string
 */
function base_path(string $path = ''): string
{
    return path_combine(BASE_PATH, $path);
}

/**
 * 应用路径
 * @param string $path
 * @return string
 */
function app_path(string $path = ''): string
{
    return path_combine(BASE_PATH . DIRECTORY_SEPARATOR . 'application', $path);
}

/**
 * 对外访问的开放目录
 * @param string $path
 * @return string
 */
function public_path(string $path = ''): string
{
    return path_combine(BASE_PATH . DIRECTORY_SEPARATOR . 'public', $path);
}

/**
 * 配置文件路径
 * @param string $path
 * @return string
 */
function config_path(string $path = ''): string
{
    return path_combine(BASE_PATH . DIRECTORY_SEPARATOR . 'config', $path);
}

/**
 * 运行时路径
 *  - 在mac或者linux环境下面，注意需要设置runtime目录权限为777
 * @param string $path
 * @return string
 */
function runtime_path(string $path = ''): string
{
    return path_combine(BASE_PATH . DIRECTORY_SEPARATOR . 'runtime', $path);
}
